import { HsAdminInput, HsAdminPage, HsAdminSelect, HsAdminSpin } from '@hs-admin/base-components'
import { Button, Flex, Tooltip, Form, Row, Col, Popconfirm, Radio, RadioChangeEvent } from 'antd'
import { DeleteOutlined, QuestionCircleOutlined } from '@ant-design/icons'
import { message, usePage } from '@hs-admin/utils'
import { FC, memo, useEffect, useMemo, useRef, useState } from 'react'
import {
  addAreaSetting,
  addCompanyListSetting,
  addIndustrySetting,
  addParkSetting,
  addPolymerizeSetting,
  addTimeSetting,
  deleteSetting,
  editAreaSetting,
  editCompanyListSetting,
  editIndustrySetting,
  editParkSetting,
  editPolymerizeSetting,
  editTimeSetting,
  getAreaDetail,
  getCompanyListDetail,
  getDataItemSettingList,
  getIndustryDetail,
  getParkDetail,
  getPolymerizeDetail,
  getSyncSettings,
  getTimeDetail,
  updateSyncSettings
} from '@/api/assetMaintain/basic/item'
import { dataItemSettingType } from '@/utils/type'
import { reqDataItemColumns } from '@hs-admin/api'
import { useImmer } from 'use-immer'
import _ from 'lodash'

interface Props {
  id: string | null
  tableData: any[]
}
const Setting: FC<Props> = (props: Props) => {
  const { id, tableData } = props
  const [form] = Form.useForm()
  const [typeOptions, setTypeOptions] = useState(dataItemSettingType())
  const fieldList = useMemo(() => {
    let list: any[] = []
    if (tableData.length) {
      list = tableData.map((item) => ({
        label: item.name,
        value: item.name,
        comment: item.comment
      }))
    }
    return list
  }, [tableData])
  const [sync_mode, setsync_mode] = useState('whole')
  const [sync_config, setsync_config] = useState({
    update_time_column_name: null,
    logical_delete: {
      column_name: null,
      equals_value: null
    }
  })
  const [loading, setloading] = useState(true)
  const allColumnList = useRef<any[]>([])
  const [typeInfor, settypeInfor] = useImmer<any>({
    columnList: [],
    tableList: []
  })

  const getSync = () => {
    getSyncSettings({ id }).then((res) => {
      setsync_mode(res.sync_mode)
      setsync_config({
        ...sync_config,
        ...res.sync_config,
        logical_delete: {
          ...sync_config.logical_delete,
          ...res.sync_config.logical_delete
        }
      })
    })
  }
  const radioChange = (e: RadioChangeEvent) => {
    const { value } = e.target
    if (value === 'whole') {
      updateSyncSettings({
        id,
        sync_mode: value,
        sync_config: {}
      }).then(() => {
        setsync_mode(value)
        setsync_config({
          update_time_column_name: null,
          logical_delete: {
            column_name: null,
            equals_value: null
          }
        })
        message.success('保存成功')
      })
    } else {
      setsync_mode(value)
    }
  }
  const syncConfigChange = (key: string, value: string) => {
    setsync_config((prev: any) => {
      if (key.includes('.')) {
        const parentField = key.split('.')[0]
        const childField = key.split('.')[1]
        prev[parentField][childField] = value
      } else {
        prev[key] = value
      }
      Reflect.deleteProperty(prev, 'type_')
      if (!prev.update_time_column_name || !prev.logical_delete.column_name || !prev.logical_delete.equals_value) {
        return { ...prev }
      }
      updateSyncSettings({
        id,
        sync_mode,
        sync_config: prev
      }).then(() => {
        message.success('保存成功')
        getSync()
      })
      return { ...prev }
    })
  }

  const callList = () => {
    setloading(true)
    return getDataItemSettingList({ data_product_id: id, page: pagination.current, page_size: pagination.pageSize })
      .then((res) => {
        const pList: any[] = []
        res.items.forEach((item: { type: any; id: any; column: string; disabled: boolean; updateType: string }) => {
          switch (item.type) {
            case 'polymerize':
              pList.push(getPolymerizeDetail({ id: item.id }))
              break
            case 'area':
              pList.push(
                getAreaDetail({ id: item.id }).then((res) => ({
                  ...res,
                  city_code_column: res.city_code_column || null,
                  area_code_column: res.area_code_column || null,
                  old_province_code_column: res.province_code_column,
                  old_city_code_column: res.city_code_column,
                  old_area_code_column: res.area_code_column,
                  old_column: res.column
                }))
              )
              break
            case 'park':
              pList.push(
                getParkDetail({ id: item.id }).then((res) => ({
                  ...res,
                  disabled: res.column === 'carrier_list'
                }))
              )
              break
            case 'time':
              pList.push(getTimeDetail({ id: item.id }))
              break
            case 'industry':
              pList.push(
                getIndustryDetail({ id: item.id }).then((res) => ({
                  ...res,
                  disabled: res.column === 'hs_ind_list'
                }))
              )
              break
            case 'company-list':
              pList.push(getCompanyListDetail({ id: item.id }))
              break
            default:
              break
          }
        })
        Promise.all(pList)
          .then((res) => {
            form.setFieldValue(
              'settingList',
              res.map((item: any) => ({ ...item, updateType: 'edit' }))
            )
            settypeInfor((prev: { tableList: any }) => {
              prev.tableList = _.cloneDeep(res)
            })
          })
          .finally(() => {
            setloading(false)
          })
        return res
      })
      .catch(() => {
        setloading(false)
      })
  }
  const { pagination }: { pagination: UsePageProps } = usePage(callList)

  // 筛选项类型
  const typeChange = (key: number, value: string) => {
    const settingList = form.getFieldValue('settingList')
    const item = settingList[key]
    const onceAddList = ['area', 'park', 'industry', 'company-list']
    const hasItem = settingList.slice(0, -1).find((item: { type: string }) => item.type === value)
    if (onceAddList.includes(value) && hasItem) {
      message.warning('区域筛选、园区筛选、产业筛选、企业白名单筛选只能添加一次')
      item.type = ''
      form.setFieldValue('settingList', settingList)
      return
    }
    item.type = value
    item.id = id
    const handleImmobilizationColumn = () => {
      item.disabled = true
      const findItem: any = allColumnList.current.find((ele: any) => ele.name === item.column)
      item.name = findItem?.comment
      form.setFieldValue('settingList', settingList)
      handleChange(settingList, key, item)
    }
    // 园区
    if (item.type === 'park') {
      item.column = 'carrier_list'
      handleImmobilizationColumn()
      return
    }
    // 产业
    if (item.type === 'industry') {
      item.column = 'hs_ind_list'
      handleImmobilizationColumn()
      return
    }
    if (value === 'area') {
      Reflect.deleteProperty(item, 'column')
      item.province_code_column = null
      item.city_code_column = null
      item.area_code_column = null
    }
    form.setFieldValue('settingList', settingList)
  }
  const handleErrorFn = async (fn: (arg0: any) => any, params: any) => {
    try {
      return await fn(params)
    } catch (error) {
      Promise.reject(error)
    }
  }
  const handleChange = async (settingList: any, key: number, params: any) => {
    setloading(true)
    const { updateType, type } = settingList[key]
    if (updateType === 'add') {
      let editRes
      switch (type) {
        case 'polymerize':
          editRes = await handleErrorFn(addPolymerizeSetting, params)
          break
        case 'area':
          editRes = await handleErrorFn(addAreaSetting, params)
          break
        case 'park':
          editRes = await handleErrorFn(addParkSetting, params)
          break
        case 'time':
          editRes = await handleErrorFn(addTimeSetting, params)
          break
        case 'industry':
          editRes = await handleErrorFn(addIndustrySetting, params)
          break
        case 'company-list':
          editRes = await handleErrorFn(addCompanyListSetting, params)
          break
        default:
          break
      }
      if (editRes) {
        message.success('保存成功')
        return callList()
      } else {
        setloading(false)
        return false
      }
    } else {
      const item = settingList[key]
      let editRes
      let res
      switch (type) {
        case 'polymerize':
          editRes = await handleErrorFn(editPolymerizeSetting, params)
          res = await handleErrorFn(getPolymerizeDetail, { id: item.id })
          break
        case 'area':
          editRes = await handleErrorFn(editAreaSetting, params)
          res = await handleErrorFn(getAreaDetail, { id: item.id })
          res = {
            ...res,
            city_code_column: res.city_code_column || null,
            area_code_column: res.area_code_column || null,
            old_province_code_column: res.province_code_column,
            old_city_code_column: res.city_code_column,
            old_area_code_column: res.area_code_column,
            old_column: res.column
          }
          break
        case 'park':
          editRes = await handleErrorFn(editParkSetting, params)
          res = await handleErrorFn(getParkDetail, { id: item.id })
          if (res.column === 'carrier_list') {
            res.disabled = true
          }
          break
        case 'time':
          editRes = await handleErrorFn(editTimeSetting, params)
          res = await handleErrorFn(getTimeDetail, { id: item.id })
          break
        case 'industry':
          editRes = await handleErrorFn(editIndustrySetting, params)
          res = await handleErrorFn(getIndustryDetail, { id: item.id })
          if (res.column === 'hs_ind_list') {
            res.disabled = true
          }
          break
        case 'company-list':
          editRes = await handleErrorFn(editCompanyListSetting, params)
          res = await handleErrorFn(getCompanyListDetail, { id: item.id })
          break
        default:
          break
      }
      settingList[key] = {
        ...res,
        updateType: 'edit'
      }
      form.setFieldValue('settingList', [...settingList])
      if (editRes) {
        message.success('保存成功')
      }
      setloading(false)
    }
  }
  // 筛选字段
  const columnChange = async (key: number, value: string, option: { comment: any }) => {
    const settingList = form.getFieldValue('settingList')
    const item = settingList[key]
    if (!item.type) {
      message.warning('请先选择筛选项类型')
      item.column = ''
      item.province_code_column = ''
      form.setFieldValue('settingList', settingList)
      return
    }
    // 区域
    if (item.type === 'area') {
      if (item.city_code_column === value) {
        message.warning('市级已选过此字段')
        item.province_code_column = item.old_province_code_column || null
        form.setFieldValue('settingList', settingList)
        return
      }
      if (item.area_code_column === value) {
        message.warning('区县级已选过此字段')
        item.province_code_column = item.old_province_code_column || null
        form.setFieldValue('settingList', settingList)
        return
      }
    }
    item.name ||= option.comment
    // 新增
    if (item.updateType === 'add') {
      let params: any = { id, ...item, column: value }
      if (item.type === 'area') {
        params = {
          id,
          ...item,
          province_code_column: value,
          city_code_column: item.city_code_column || '',
          area_code_column: item.area_code_column || ''
        }
      }
      const flag = await handleChange(settingList, key, params)
      if (!flag) {
        if (item.type === 'area') {
          item.province_code_column = item.old_province_code_column || null
        } else {
          item.column = item.old_column || ''
        }
      }
    } else {
      let params = { ...item, column: value }
      if (item.type === 'area') {
        params = {
          ...item,
          province_code_column: value,
          city_code_column: item.city_code_column || '',
          area_code_column: item.area_code_column || ''
        }
      }
      handleChange(settingList, key, params)
    }
  }
  // 市级
  const cityChange = (key: number, value: string) => {
    const settingList = form.getFieldValue('settingList')
    const item = settingList[key]
    if (!item.province_code_column) {
      item.city_code_column = null
      message.warning('请先选省级字段')
      return
    }
    if (item.province_code_column === value) {
      message.warning('省级已选过此字段')
      item.city_code_column = item.old_city_code_column || ''
      form.setFieldValue('settingList', settingList)
      return
    }
    if (item.area_code_column === value) {
      message.warning('区县级已选过此字段')
      item.city_code_column = item.old_city_code_column || ''
      form.setFieldValue('settingList', settingList)
      return
    }
    if (item.updateType === 'add') {
      const params = { id, ...item, city_code_column: value || '', area_code_column: item.area_code_column || '' }
      handleChange(settingList, key, params)
    } else {
      const params = { ...item, city_code_column: value || '', area_code_column: item.area_code_column || '' }
      handleChange(settingList, key, params)
    }
  }
  // 区县级
  const districtChange = (key: number, value: string) => {
    const settingList = form.getFieldValue('settingList')
    const item = settingList[key]
    if (!item.province_code_column) {
      item.area_code_column = null
      message.warning('请先选省级字段')
      return
    }
    if (!item.city_code_column) {
      item.area_code_column = null
      message.warning('请先选市级字段')
      return
    }
    if (item.province_code_column === value) {
      message.warning('省级已选过此字段')
      item.area_code_column = item.old_area_code_column || ''
      form.setFieldValue('settingList', settingList)
      return
    }
    if (item.city_code_column === value) {
      message.warning('市级已选过此字段')
      item.area_code_column = item.old_area_code_column || ''
      form.setFieldValue('settingList', settingList)
      return
    }
    if (item.updateType === 'add') {
      const params = { id, ...item, area_code_column: value || '' }
      handleChange(settingList, key, params)
    } else {
      const params = { ...item, area_code_column: value || '' }
      handleChange(settingList, key, params)
    }
  }
  // 筛选项名称
  const nameChange = (key: number, value: string) => {
    const settingList = form.getFieldValue('settingList')
    const item = settingList[key]
    if (!item.type) {
      message.warning('请先选择筛选项类型')
      return
    }
    if (item.updateType === 'add') {
      const params = { id, ...item, name: value }
      handleChange(settingList, key, params)
    } else {
      const params = { ...item, name: value }
      handleChange(settingList, key, params)
    }
  }

  useEffect(() => {
    getSync()
    reqDataItemColumns({
      id
    }).then((res) => {
      allColumnList.current = res
      settypeInfor((prev: { columnList: any }) => {
        prev.columnList = res
      })
    })
  }, [])

  useEffect(() => {
    const { columnList, tableList } = typeInfor
    // 园区筛选
    const hasParkItem = columnList.find((item: { name: string }) => item.name === 'carrier_list')
    const listHasPark = tableList.find((item: { type: string }) => item.type === 'park')
    setTypeOptions((prev: any[]) => {
      const _index = prev.findIndex((item) => item.value === 'park')
      if (!hasParkItem || listHasPark) {
        prev[_index].disabled = true
      } else {
        prev[_index].disabled = false
      }
      return [...prev]
    })

    // 产业筛选
    const hasIndustryItem = columnList.find((item: { name: string }) => item.name === 'hs_ind_list')
    const listHasIndustry = tableList.find((item: { type: string }) => item.type === 'industry')
    setTypeOptions((prev: any[]) => {
      const _index = prev.findIndex((item) => item.value === 'industry')
      if (!hasIndustryItem || listHasIndustry) {
        prev[_index].disabled = true
      } else {
        prev[_index].disabled = false
      }
      return [...prev]
    })
  }, [typeInfor])

  return (
    <>
      {loading && <HsAdminSpin />}
      <h2>同步方式配置</h2>
      <Radio.Group onChange={radioChange} value={sync_mode} className="mt-2">
        <Radio value={'whole'}>仅支持全量同步</Radio>
        <Radio value={'time_offset'}>支持全量同步和增量同步</Radio>
      </Radio.Group>
      {sync_mode === 'time_offset' && (
        <>
          <Row gutter={16} className="mt-2">
            <Col span={2}></Col>
            <Col span={8}>
              <Flex gap={'small'} align="center">
                <span className="flex-none">增量时间字段选择：</span>
                <span className="flex-none">字段</span>
                <HsAdminSelect
                  options={fieldList}
                  value={sync_config.update_time_column_name}
                  placeholder="请选择增量时间字段"
                  className="w-full"
                  onChange={(value: string) => syncConfigChange('update_time_column_name', value)}
                  allowClear={false}
                />
              </Flex>
            </Col>
          </Row>
          <Row gutter={16} className="mt-2">
            <Col span={2}></Col>
            <Col span={8}>
              <Flex gap={'small'} align="center">
                <span className="flex-none">数据有效识别规则：</span>
                <span className="flex-none">字段</span>
                <HsAdminSelect
                  options={fieldList}
                  value={sync_config.logical_delete?.column_name}
                  placeholder="请选择数据有效识别规则"
                  className="w-full"
                  onChange={(value: string) => syncConfigChange('logical_delete.column_name', value)}
                  allowClear={false}
                />
              </Flex>
              <p className="ml-42 mt-2">* 三项内容填写完成后自动保存</p>
            </Col>
            <Col span={8}>
              <Flex gap={'small'} align="center">
                <span className="flex-none">=</span>
                <HsAdminInput
                  defaultValue={sync_config.logical_delete?.equals_value}
                  placeholder="请输入表达式"
                  onPressEnter={(e: { target: { value: string } }) => syncConfigChange('logical_delete.equals_value', e.target.value)}
                  onBlur={(e: { target: { value: string } }) => syncConfigChange('logical_delete.equals_value', e.target.value)}
                  allowClear={false}
                />
              </Flex>
            </Col>
          </Row>
        </>
      )}
      <br />
      <br />
      <Flex gap={'small'} align="center">
        <h2>筛选配置</h2>
        <Tooltip title="在数据数据查询和数据提供时（导出、接口、任务传输等形式），以下配置内容可作为数据范围的选择维度">
          <QuestionCircleOutlined />
        </Tooltip>
      </Flex>
      <Form form={form}>
        <Form.List name="settingList">
          {(fields, { add }) => (
            <>
              {!!fields?.length && (
                <Row gutter={16}>
                  <Col span={5}>
                    <Flex justify="center">筛选项类型</Flex>
                  </Col>
                  <Col span={5}>
                    <Flex justify="center" align="center" gap={'small'}>
                      <b style={{ color: 'red' }}>*</b>筛选字段
                    </Flex>
                  </Col>
                </Row>
              )}
              {fields.map(({ key, name, ...restField }) => (
                <Row key={key} gutter={16} className="mt-2">
                  <Col span={5}>
                    <Flex gap={'small'}>
                      <Popconfirm
                        title="警告"
                        description="确定删除该项吗?"
                        onConfirm={() => {
                          const settingList = form.getFieldValue('settingList')
                          const item = settingList[key]
                          if (item.id && item.updateType === 'edit') {
                            deleteSetting({ id: item.id }).then(() => {
                              message.success('删除成功')
                              callList()
                            })
                          } else {
                            settingList.splice(key, 1)
                            form.setFieldValue('settingList', settingList)
                          }
                        }}>
                        <DeleteOutlined className="mb-6" />
                      </Popconfirm>
                      {/* 筛选项类型 */}
                      <Form.Item {...restField} name={[name, 'type']} rules={[{ required: true, message: '请选择筛选项类型' }]} className="w-full">
                        <HsAdminSelect
                          options={typeOptions}
                          placeholder="请选择筛选项类型"
                          onChange={(value: string) => typeChange(key, value)}
                          allowClear={false}
                          disabled={form.getFieldValue('settingList')[key]?.updateType === 'edit' ? true : false}
                        />
                      </Form.Item>
                    </Flex>
                  </Col>
                  <Col span={4}>
                    {/* 筛选字段 */}
                    <Form.Item
                      label={form.getFieldValue('settingList')[key]?.type === 'area' ? '省级' : ''}
                      {...restField}
                      name={[name, form.getFieldValue('settingList')[key]?.type === 'area' ? 'province_code_column' : 'column']}
                      rules={[{ required: true, message: '请选择' }]}>
                      <HsAdminSelect
                        options={fieldList}
                        placeholder="请选择筛选字段"
                        onChange={(value: string, option: { comment: any }) => columnChange(key, value, option)}
                        allowClear={false}
                        disabled={form.getFieldValue('settingList')[key]?.disabled}
                      />
                    </Form.Item>
                  </Col>

                  <Col span={4}>
                    {form.getFieldValue('settingList')[key]?.type === 'area' && (
                      <Form.Item label="市级" {...restField} name={[name, 'city_code_column']}>
                        <HsAdminSelect options={fieldList} placeholder="请选择市级" onChange={(value: string) => cityChange(key, value)} />
                      </Form.Item>
                    )}
                  </Col>
                  <Col span={4}>
                    {form.getFieldValue('settingList')[key]?.type === 'area' && (
                      <Form.Item label="区县级" {...restField} name={[name, 'area_code_column']}>
                        <HsAdminSelect options={fieldList} placeholder="请选择区县级" onChange={(value: string) => districtChange(key, value)} />
                      </Form.Item>
                    )}
                  </Col>

                  <Col span={7}>
                    <Form.Item label="筛选项名称" {...restField} name={[name, 'name']}>
                      <HsAdminInput
                        placeholder="请输入筛选项名称"
                        onPressEnter={(e: { target: { value: string } }) => nameChange(key, e.target.value)}
                        onBlur={(e: { target: { value: string } }) => nameChange(key, e.target.value)}
                      />
                    </Form.Item>
                  </Col>
                </Row>
              ))}
              <Form.Item>
                <Button
                  type="primary"
                  onClick={() => {
                    const settingList = form.getFieldValue('settingList')
                    if (settingList.length && !settingList.at(-1).type) {
                      message.warning('只能有一条空白数据，请先将空白数据填写完再添加')
                      return
                    }
                    add({ type: null, updateType: 'add', column: null, name: '' })
                  }}>
                  + 增加筛选项
                </Button>
              </Form.Item>
            </>
          )}
        </Form.List>
      </Form>
      <Flex justify="end">
        <HsAdminPage {...pagination} />
      </Flex>
      <br />
    </>
  )
}

export default memo(Setting)
